import queue
import socket
import sys
import threading

import numpy as np
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui

# 创建一个UDP套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
localhost = '192.168.137.1'
remotehost = '192.168.137.142'
MaxloadNum = 2000
rmsWindows = 8

# 绑定到一个地址和端口
server_address = (localhost, 8080)
sock.bind(server_address)
sock.setblocking(False)
data, addr = None, None
q = queue.Queue()
x = 0

# 定义一个全局变量用于存储数据
data_list = []
data_queue = []

data_queuerms = []


def update_plot():
    """
    更新绘图
    """
    global data_list, data_queue
    # 从队列中获取数据
    while len(data_queue) > 0:
        data = data_queue.pop(0)
        data_list.extend(data)
    if len(data_list) > MaxloadNum:
        data_list = data_list[-MaxloadNum:]

    curve.setData(data_list)


def drawtask():
    # 创建一个图形窗口
    app = QtGui.QApplication(sys.argv)
    win = pg.GraphicsWindow(title="Real-time Plotting")

    # 创建一个PlotItem，用于绘制图形
    plot_item = win.addPlot(title="Data Plot")

    # 创建一个CurveItem，用于绘制数据曲线
    curve_item = plot_item.plot(pen='y')

    # 设置窗口缓存最多10000个点
    plot_item.setMaximumCacheSize(10000)


def OrderTransmit(data1, data2):
    # 消息内容,两个uint32_t数据
    # 将数据转换为二进制格式

    data1 = 42
    data2 = 1337
    data_bin = (data1.to_bytes(4, 'big') + data2.to_bytes(4, 'big'))
    # 向单片机发送数据
    sock.sendto(data_bin, addr)


def CommandExecute(command):
    # command格式为"set ch tensity"，解析参数并调用SetTensity()函数
    command = command.strip().split()
    if command[0].lower() == "set":
        if len(command) == 3:
            ch, tensity = int(command[1]), int(command[2])
            SetTensity(ch, tensity)
    elif command[0].lower() == "sw":
        if len(command) == 4:
            Set_Waveform(command[1], command[2], command[3])
        else:
            print("Invalid command format")
            return


def SetTensity(ch, tensity):
    global addr
    """
    设定通道ch电刺激强度为tensity
    :param ch:-
    :param tensity:
    :return: None
    """
    # 发送8字节的指令数据
    hex_num = '0x41'
    data1 = int(hex_num, 16)
    tensity = min(tensity, 4095)

    data_bin = (data1.to_bytes(4, 'big') +
                ch.to_bytes(2, 'big') + tensity.to_bytes(2, 'big'))
    # 向单片机发送数据
    sock.sendto(data_bin, addr)


def Set_Waveform(worktime, lastingtime, holdtime):
    """
    :param worktime:
    :param lastingtime:
    :param holdtime:
    """
    # 发送8字节的指令数据
    print("sending:")

    hex_num = '0x43'
    data1 = int(hex_num, 16)
    lastingtime = int(lastingtime)
    worktime = int(worktime)
    holdtime = int(holdtime)
    print(worktime, lastingtime, holdtime)

    data_bin = (data1.to_bytes(4, 'big')
                + worktime.to_bytes(2, 'big')
                + lastingtime.to_bytes(1, 'big')
                + holdtime.to_bytes(1, 'big'))
    sock.sendto(data_bin, addr)


# def main():
#     global addr, data
#
#     print("等待接收消息...")
#     while True:
#         # 接收数据
#         try:
#             data, addr = sock.recvfrom(1024)
#             print("收到消息:", data.decode('utf-8'), "来自:", addr)
#             break
#         except socket.error as e:
#             if e.errno == socket.EAGAIN:
#                 # 无数据可用，正常情况
#                 continue
#                 pass
#
#     while True:
#         # 接收数据
#         try:
#             data, addr = sock.recvfrom(1024)
#             # data是以\n分隔开，将其转换为列表加入到data_queue
#             # print(data)
#             # 在请求数据时会发送空字节数据
#
#             if data != b'':
#                 numarray = np.genfromtxt(data.decode('utf-8').splitlines(), dtype=int, delimiter=',')
#                 if numarray.size != 20:
#                     print("hi")
#                     print(numarray == 0x43)
#                     print("received data")
#                     continue
#
#                 open_ele_on = 1
#
#                 if not open_ele_on:
#                     data_queue.append(numarray)
#                 else:
#
#                     rms = np.sqrt(np.mean(np.square(numarray)))
#                     data_queue.append([rms])
#                     data_queuerms.append(rms)
#
#                     if len(data_queuerms) == rmsWindows:
#                         target = np.mean(data_queuerms)
#                         if target > 1700:
#                             Set_Waveform(2000, 100, 50)
#                             print("大电")
#                         elif target > 1680:
#                             Set_Waveform(500, 100, 25)
#                             print("小电")
#                         elif target > 1650:
#                             Set_Waveform(500, 25, 25)
#                             print("小小电")
#                         data_queuerms.clear()
#
#                 # 求均方根
#
#                 # print(numarray.size)
#             # print("收到消息:", data.decode('utf-8'), "来自:", addr)
#         except socket.error as e:
#             if e.errno == socket.EAGAIN:
#                 # 无数据可用，正常情况
#                 continue
#                 pass
#
#         # 处理命令
#         if q.empty() is False:
#             print("发送命令")
#             CommandExecute(q.get())

        # message = "nihao"

        # numarray = np.genfromtxt(data.decode('utf-8').splitlines(), dtype=int, delimiter=',')
        # print(numarray)


def execute_command():
    while True:
        command = input("请输入命令：")
        print(f"执行命令：{command}")
        q.put(command)


def start_UI():
    plt = pg.plot()

    # 设置图表属性
    plt.setWindowTitle('Real-time Data Plot')
    plt.setLabel('left', 'Data', color='white')
    plt.setLabel('bottom', 'Time', color='white')
    plt.setBackground((0, 0, 0))
    plt.setBackground((255, 255, 255))
    # 创建一个数据线
    curve = plt.plot(pen='black')

    # 设置参数
    pg.setConfigOptions(antialias=True)

    # 创建一个定时器，用于更新图表
    timer = QtCore.QTimer()
    timer.timeout.connect(update_plot)
    timer.start(100)  # 每隔100ms更新一次图表

    t1 = threading.Thread(target=main)
    t2 = threading.Thread(target=execute_command)

    t1.start()
    t2.start()

    # 显示图表
    sys.exit(pg.exec())


if __name__ == "__main__":
    # 创建一个图表
    plt = pg.plot()

    # 设置图表属性
    plt.setWindowTitle('Real-time Data Plot')
    plt.setLabel('left', 'Data', color='white')
    plt.setLabel('bottom', 'Time', color='white')
    plt.setBackground((0, 0, 0))
    plt.setBackground((255, 255, 255))
    # 创建一个数据线
    curve = plt.plot(pen='black')

    # 设置参数
    pg.setConfigOptions(antialias=True)

    # 创建一个定时器，用于更新图表
    timer = QtCore.QTimer()
    timer.timeout.connect(update_plot)
    timer.start(100)  # 每隔100ms更新一次图表

    t1 = threading.Thread(target=main)
    t2 = threading.Thread(target=execute_command)

    t1.start()
    t2.start()

    # 显示图表
    sys.exit(pg.exec())
